#pragma once
#ifndef __BASE_MENU_H_
#define __BASE_MENU_H_

#include <vector>
#include "BaseMenuItem.h"
#include "glTextDrawer.h"
#include "Ptr.hpp"

class BaseMenu
{
protected:
  SimpleFont __font;
  float __longitude, __latitude, __globeRadius;
  std::vector< Ptr< BaseMenuItem > > __items;

  virtual unsigned int __getItemIndex (float longitude, float latitude) = 0;

public:
  enum Status { HIDE, HIDE_TO_SHOW, SHOW, SHOW_TO_HIDE } status;

  BaseMenu(const wchar_t* fontFamily, int fontSize, float globeRadius)
    : status (HIDE), __font (fontFamily, fontSize),
    __globeRadius (globeRadius) {}

  virtual void draw () const = 0;
  virtual void doAnimation () = 0;
  virtual void addMenuItem (const std::wstring& itemLabel) = 0;

  virtual std::wstring mouseReleased (float longitude, float latitude)
  {
    int selectIndex = __getItemIndex (longitude, latitude);
    if (selectIndex == -1) return L"";
    return __items[selectIndex]->label;
  }
  
  virtual void mouseDrag (float longitude, float latitude)
  {
    unsigned int overIndex = __getItemIndex (longitude, latitude);
    for (size_t i = 0; i < __items.size (); ++i)
    {
      if (i == overIndex)
        __items[i]->rollOver ();
      else
        __items[i]->rollOut ();
    }
  }
  
  virtual void showMenu (float longitude, float latitude)
  {
    if (status == HIDE)
    {
      __longitude = longitude;
      __latitude = latitude;
      status = HIDE_TO_SHOW;
      for (size_t i = 0; i < __items.size (); ++i)
      {
        __items[i]->status = BaseMenuItem::HIDE_TO_NORMAL;
      }
    }
  }

  virtual void hideMenu ()
  {
    if (status != HIDE)
    {
      status = SHOW_TO_HIDE;
      for (size_t i = 0; i < __items.size (); ++i)
      {
        __items[i]->rollOut ();
        __items[i]->status = BaseMenuItem::NORMAL_TO_HIDE;
      }
    }
  }

  virtual bool changeItemName (const std::wstring& oldName,
    const std::wstring& newName)
  {
    for (size_t i = 0; i < __items.size (); ++i)
    {
      if (__items[i]->label == oldName)
      {
        __items[i]->label = newName;
        return true;
      }
    }
    return false;
  }

  void setGlobeRadius (float globeRadius) { __globeRadius = globeRadius; }

  float getLongitude () const { return __longitude; }
  float getLatitude () const { return __latitude; }
};

#endif